/**
 * 数据库连接池配置模块
 * 负责创建和管理 MySQL 数据库连接池，供其他模块使用
 */

// 导入依赖模块
import dotenv from 'dotenv';
import mysql from 'mysql2/promise';

// 加载环境变量配置
// 从项目根目录的 .env 文件中读取配置信息
dotenv.config();

/**
 * 数据库连接配置对象
 * 从环境变量中获取配置，如环境变量不存在则使用默认值
 */
const config = {
  host: process.env.MYSQL_HOST || 'localhost',    // 数据库主机名
  port: parseInt(process.env.MYSQL_PORT) || 3306, // 数据库端口号（转换为数字类型）
  user: process.env.MYSQL_USER || 'root',         // 数据库用户名
  password: process.env.MYSQL_PASSWORD || 'Dy459901', // 数据库密码
  database: process.env.MYSQL_DATABASE || 'hrms_small_biz', // 数据库名称
  connectionLimit: 10, // 连接池最大连接数
  queueLimit: 0,       // 等待队列无限制（0 表示不限制）
  waitForConnections: true, // 当无连接可用时等待，而不是立即抛出错误
  enableKeepAlive: true, // 启用连接保活机制
  keepAliveInitialDelay: 30000 // 连接保活初始延迟（毫秒）
};

/**
 * 创建 MySQL 连接池
 * 连接池负责管理数据库连接的创建、复用和释放
 */
const pool = mysql.createPool(config);

/**
 * 测试数据库连接是否正常
 * @param {Object} options - 测试选项
 * @param {number} options.retries - 连接失败时的重试次数（默认：3次）
 * @param {number} options.retryDelay - 重试间隔（毫秒，默认：1000ms）
 * @param {number} options.timeout - 连接超时时间（毫秒，默认：5000ms）
 * @returns {Promise<boolean>} 连接成功返回true，失败返回false
 */
async function testConnection(options = {}) {
  const { retries = 3, retryDelay = 1000, timeout = 5000 } = options;
  let attempt = 0;
  
  while (attempt <= retries) {
    const timestamp = new Date().toISOString();
    attempt++;
    
    try {
      // 创建带超时的连接Promise
      const connectionPromise = pool.getConnection();
      const timeoutPromise = new Promise((_, reject) => 
        setTimeout(() => reject(new Error(`Connection timeout after ${timeout}ms`)), timeout)
      );
      
      // 使用Promise.race实现超时控制
      const connection = await Promise.race([connectionPromise, timeoutPromise]);
      
      if (attempt > 1) {
        console.log(`[${timestamp}] [INFO] 数据库连接重试成功 - 第${attempt}次尝试 - 主机: ${config.host}, 端口: ${config.port}, 数据库: ${config.database}`);
      } else {
        console.log(`[${timestamp}] [INFO] 数据库连接成功 - 主机: ${config.host}, 端口: ${config.port}, 数据库: ${config.database}`);
      }
      
      connection.release(); // 释放连接回池中
      return true;
    } catch (error) {
      // 如果是最后一次尝试则记录详细错误
      const isLastAttempt = attempt === retries;
      const prefix = isLastAttempt ? '[ERROR]' : '[WARNING]';
      
      console.log(`[${timestamp}] ${prefix} 数据库连接${isLastAttempt ? '失败' : '尝试失败'} - 第${attempt}次尝试 - 主机: ${config.host}, 端口: ${config.port}`);
      console.log(`[${timestamp}] ${prefix} 错误类型: ${error.code || 'UNKNOWN_ERROR'}`);
      console.log(`[${timestamp}] ${prefix} 错误详情: ${error.message}`);
      
      // 如果不是最后一次尝试，则等待一段时间后重试
      if (!isLastAttempt) {
        console.log(`[${timestamp}] [INFO] 将在${retryDelay}ms后重试连接...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        // 最后一次尝试仍然失败，返回false
        return false;
      }
    }
  }
  
  // 理论上不会执行到这里，但为了类型安全返回false
  return false;
}

// 导出连接池和相关函数
export { pool, testConnection };
